<!DOCTYPE html>
<meta charset="utf-8">
<style>

.node circle {
  cursor: pointer;
  stroke-width: 1.5px;
}

.node text {
  fill: #252929;
  font-weight: bold;
  text-shadow: 0 0 0.2em white;
  pointer-events: none;
  text-anchor: middle;
}

line.link {
  fill: none;
  stroke: #9ecae1;
  stroke-width: 1.5px;
}

</style>
<body>
<div><button id="refreshButton" type="button" onclick="refresh()">Refresh</button><button id="drawButton" type="button" onclick="getData()">Draw</button></div>
<script src="js/d3.min.js"></script>
<script>

var smellColor = ["#C0F864", "#559ACB","#FF8C61","#FFBA61", "#378B2E", "#AA9739", "#90305A", "#52606F", "#AA8779", "#882700","transparent"];
  
var smellName = ["Shotgun Surgery","Feature Envy","Dispersed Coupling","God Class","Refused Parent Bequest","Brain Class","Brain Method","Data Class","Intensive Coupling","Tradition Breaker"];

var width = 1400,
    height = 1400,
    root;

var force = d3.layout.force()
    .linkDistance(80)
    .charge(-220)
    .gravity(.05)
    .size([width, height])
    .on("tick", tick);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

var link = svg.selectAll(".link"),
    node = svg.selectAll(".node");
    
function refresh() {
	window.location.reload();
}

function getData() { //Begin getData
	root = JSON.parse(getIntraClassAgglomerationsDataFeed(3));

	update();
}

function update() {
  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);

  // Restart the force layout.
  force
      .nodes(nodes)
      .links(links)
      .start();

  // Update links.
  link = link.data(links, function(d) { return d.target.id; });

  link.exit().remove();

  link.enter().insert("line", ".node")
      .attr("class", "link");

  // Update nodes.
  node = node.data(nodes, function(d) { return d.id; });

  node.exit().remove();

  var nodeEnter = node.enter().append("g")
      .attr("class", "node")
      .on("click", click)
      .on("mouseover", mouseover)
      .on("mouseout", mouseout)
      .on("contextmenu", function(d){
    		//handle right click    		
    		var kind = "";
    	    var clazz = d.name.split("@")[1].split("#")[0];
    	    if(clazz.indexOf(".") > -1) {
    	    	 kind = clazz.split(".")[1];
    	    	 clazz = clazz.split(".")[0];    	    	 
    	    }
    	    agglomerationsEventFunction(d.packagename,clazz, kind);
   	    	//stop showing browser menu
   		     d3.event.preventDefault();
    	})
      .call(force.drag({buttons: [0, 1]}));

  nodeEnter.append("circle")
      .filter(function(d){ return d.groupid >= 0; })
      .attr("r", function(d) { return d.children ? 3.5 : Math.pow(d.size, 2/5) || 1; })
      .style("fill", function color(d) {      
          return smellColor[d.groupid];
      })      

  nodeEnter.append("image")
      .filter(function(d){ return d.groupid === -1; })
      .attr("xlink:href", "images/class.png")
      .attr("x", -8)
      .attr("y", -8)
      .attr("width", 32)
      .attr("height", 32)

  nodeEnter.append("image")
      .filter(function(d){ return d.groupid === -2; })
      .attr("xlink:href", "images/package.png")
      .attr("x", -8)
      .attr("y", -8)
      .attr("width", 40)
      .attr("height", 40)

  nodeEnter.append("image")
      .filter(function(d){ return d.groupid === -3; })
      .attr("xlink:href", "images/root.png")
      .attr("x", -8)
      .attr("y", -8)
      .attr("width", 64)
      .attr("height", 64)

  nodeEnter.append("text")
      .attr("dy", ".35em")
      .text(function(d) { return d.name; })
      .style("visibility", "hidden");

}

function tick() {
  link.attr("x1", function(d) { return d.source.x; })
      .attr("y1", function(d) { return d.source.y; })
      .attr("x2", function(d) { return d.target.x; })
      .attr("y2", function(d) { return d.target.y; });

  node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });
}

function color(d) {
  return d._children ? "#3182bd" // collapsed package
      : d.children ? "#c6dbef" // expanded package
      : "#fd8d3c"; // leaf node
}

// Toggle children on click.
function click(d) {
  if (d3.event.defaultPrevented) return; // ignore drag  
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  update();
}

function mouseover(d) {
	var name = d.name;
	svg.selectAll("text").filter(function(d){ return d !== undefined && d.name === name; }).style("visibility","visible");
};

function mouseout(d) {
	var name = d.name;
	svg.selectAll("text").filter(function(d){ return d !== undefined && d.name === name; }).style("visibility","hidden");
};


// Returns a list of all nodes under the root.
function flatten(root) {
  var nodes = [], i = 0;

  function recurse(node) {
    if (node.children) node.children.forEach(recurse);
    if (!node.id) node.id = ++i;
    nodes.push(node);
  }

  recurse(root);
  return nodes;
}

var svgReferences = svg.append("svg")
	.attr("x", 1150)
	.attr("y", 10)
	.attr("width", 300)
	.attr("height", 450);


	for(var i = 1; i < smellColor.length + 1; i++) {
	
		svgReferences.append("circle")
			.attr("cx", 30)
			.attr("cy", Math.max(i*30,30))
			.attr("r", 10)
			.style("fill", function(d) { return smellColor[i - 1]; });
		
		svgReferences.append("text")
			.attr("x", 50)
			.attr("y", Math.max(i*30 + 5,35))
			.text(smellName[i - 1]);
	}

	svgReferences.append("image")
		.attr("x", 20)
		.attr("y", (smellColor.length)*30)
		.attr("xlink:href", "images/package.png")
		.attr("width", 40)
		.attr("height", 40)   
	
	svgReferences.append("text")
		.attr("x", 70)
		.attr("y", (smellColor.length)*30 + 20)
		.text("Java Package");
	
	svgReferences.append("image")
		.attr("xlink:href", "images/class.png")
		.attr("x", 20)
		.attr("y", (smellColor.length)*30 + 50)
		.attr("width", 32)
		.attr("height", 32)
	
	svgReferences.append("text")
		.attr("x", 70)
		.attr("y", (smellColor.length)*30 + 70)
		.text("Java Class");

</script>